package com.xz;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author：xz
 * @Date：2023/3/31
 */
public class OptionalDemo {

    public static void main(String[] args) throws Throwable {
        // 编写代码时，出现的最多的就是空指针异常。所以很多情况下需要各种非空的判断
        // 引入Optional可以写出更加优雅的代码来避免空指针异常
//        Author author = getAuthors();
//        if (author != null) {
//            System.out.println(author.getName());
//        }

//        Optional<Author> optional = Optional.ofNullable(author);
//        optional.ifPresent(author1 -> System.out.println(author1.getName()));

        // 如果确定一个对象不是空，则可以使用Optional的静态方法of将数据封装成Optional对象
//        Optional<Author> optional = Optional.of(author);
        // ifPresent方法会判断其内封装的数据是否为空，不为空时才会执行具体的消费代码，这样使用起来就更加安全了
//        optional.ifPresent(author1 -> System.out.println(author1.getName()));

//        Optional<Author> optional = getAuthorsOptional();
        // 如果我们期望安全的获取值，就不i推荐使用get
//        Author author = optional.get();
        // 如果optional为空则默认Author对象中的属性全为null
//        Author author = optional.orElseGet(Author::new);
        // 如果optional为空则默认Author对象中的属性为设置的值
//        Author author = optional.orElseGet(() -> new Author(1L, "梦多", 33, "梦族", null));
//        Author author = optional.orElseThrow(() -> new RuntimeException("数据为null"));
//        System.out.println(author);

//        Optional<Author> authorsOptional = getAuthorsOptional();
//        authorsOptional.filter(author -> author.getAge() > 18).ifPresent(author -> System.out.println(author));
//
//        if (authorsOptional.isPresent()){
//            System.out.println("有数据");
//        }

        testMap();
    }

    private static void testMap() {
        getAuthorsOptional();
//        Optional<List<Book>> books = optional.map(Author::getBooks);
//        books.ifPresent(System.out::println);
    }


    private static void getAuthorsOptional() {
        // 一般使用Optional的静态方法ofNullable来将数据封装成一个Optional对象。无论传入的参数是否为null都不会出现问题
        Author author = new Author(1L, "梦多", 33, "梦族", null);
        // 书籍列表
        List<Book> books1 = new ArrayList<>();
        books1.add(new Book(1L, "刀", "哲学，爱情", 88,BigDecimal.valueOf(88), "一刀两断"));
        books1.add(new Book(2L, "一个人刀", "个人成长，爱情", 99,BigDecimal.valueOf(99), "失败刀"));
        author.setBooks(books1);
        Map<String, List<Book>> bookMap = new HashMap<>();
        bookMap.put("1",books1);
        List<Book> books = new ArrayList<>();
        BigDecimal reduce = BigDecimal.ZERO;
        if (Optional.ofNullable(bookMap).map(b -> b.get("2")).isPresent()){
            reduce = Optional.ofNullable(bookMap).map(b -> b.get("2")).get().stream().map(Book::getScoreBig).reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        System.out.println(reduce);
//        return Optional.ofNullable(author);

        // 如果一个方法的返回值类型是Optional类型并且我们经过判断发现某次计算得到的返回值是null，这个时候就需要把null封装成Optional对象返回。这时可以使用Option的静态方法empty()来精选封装
//        return author == null ? Optional.empty() : Optional.of(author);
    }

    private static Author getAuthors() {
        // 初始化数据
        Author author = new Author(1L, "梦多", 33, "梦族", null);
        return null;
//        return author;
    }
}
